﻿/*----------------------------------------------------------------
//  <copyright file="AliyunSmsTemplater.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2023-12-06 10:27</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.SMS.Templater
{
    #region "阿里云短信模板功能"
    /// <summary>
    /// 阿里云短信模板功能
    /// </summary>
    public class AliyunSmsTemplater : ISmsTemplater
    {
        #region 属性
        #region "获取 服务提供者对象"
        /// <summary>
        /// 获取 服务提供者对象
        /// </summary>
        protected IServiceProvider ServiceProvider { get; }
        #endregion
        #region "获取 事件总线"
        /// <summary>
        /// 获取 事件总线
        /// </summary>
        protected IEventBus EventBus => ServiceProvider.GetService<IEventBus>();
        #endregion
        #region "获取 日志对象"
        /// <summary>
        /// 获取 日志对象
        /// </summary>
        protected ILogger Logger { get; }
        #endregion
        #region "获取 短信配置选项"
        /// <summary>
        /// 获取 短信配置选项
        /// </summary>
        protected SmsOptions SmsOpt => ServiceProvider.GetService<IConfiguration>()?.GetSmsOptions();
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个阿里云短信模板功能的新实例"
        /// <summary>
        /// 初始化一个阿里云短信模板功能的新实例 <see cref="AliyunSmsTemplater"/> 的新实例
        /// </summary>
        /// <param name="provider"></param>
        public AliyunSmsTemplater(IServiceProvider provider)
        {
            ServiceProvider = provider;
            Logger = provider.GetLogger(GetType());
        }
        #endregion

        #endregion

        #region "方法"
        #region "申请短信模板"
        /// <summary>
        /// 申请短信模板
        /// </summary>
        /// <param name="paramsDto">短信模板参数DTO</param>
        /// <returns></returns>
        public virtual async Task<OperationResult<TempResponse>> AddAsync(TempParamsDto paramsDto)
        {
            var result = AddTemplateByAliyun(SmsOpt.RegionId, SmsOpt.Id, SmsOpt.Secret
                        , SmsOpt.Domain
                        , paramsDto);
            //触发申请成功事件
            if (result.Succeeded)
            {
                SmsTempEventData eventData = new()
                {
                    ParamsDto = paramsDto,
                    Response = result.Data,
                };
                await EventBus?.PublishAsync(this, eventData);
            }
            return await Task.Factory.StartNew(() => result);
        }
        #endregion
        #region "删除短信模板"
        /// <summary>
        /// 删除短信模板
        /// </summary>
        /// <param name="templateCode">短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。</param>
        /// <returns></returns>
        public virtual async Task<OperationResult<TempResponse>> DeleteAsync(string templateCode)
        {
            var result = DeleteTemplateByAliyun(SmsOpt.RegionId, SmsOpt.Id, SmsOpt.Secret
                        , SmsOpt.Domain
                        , templateCode);
            //触发删除成功事件
            if (result.Succeeded)
            {
                SmsTempEventData eventData = new()
                {
                    Response = result.Data,
                };
                await EventBus?.PublishAsync(this, eventData);
            }
            return await Task.Factory.StartNew(() => result);
        }
        #endregion
        #region "修改短信模板"
        /// <summary>
        /// 修改短信模板
        /// </summary>
        /// <param name="paramsDto">短信模板参数DTO</param>
        /// <returns></returns>
        public virtual async Task<OperationResult<TempResponse>> ModifyAsync(TempParamsDto paramsDto)
        {
            var result = ModifyTemplateByAliyun(SmsOpt.RegionId, SmsOpt.Id, SmsOpt.Secret
                        , SmsOpt.Domain
                        , paramsDto);
            //触发修改成功事件
            if (result.Succeeded)
            {
                SmsTempEventData eventData = new()
                {
                    ParamsDto = paramsDto,
                    Response = result.Data,
                };
                await EventBus?.PublishAsync(this, eventData);
            }
            return await Task.Factory.StartNew(() => result);
        }
        #endregion
        #region "查询短信模板"
        /// <summary>
        /// 查询短信模板
        /// </summary>
        /// <param name="templateCode">短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。</param>
        /// <returns></returns>
        public virtual async Task<OperationResult<TempDetailResponse>> QueryAsync(string templateCode)
        {
            var result = QueryTemplateByAliyun(SmsOpt.RegionId, SmsOpt.Id, SmsOpt.Secret
                        , SmsOpt.Domain
                        , templateCode);
            //触发查询成功事件
            if (result.Succeeded)
            {
                SmsTempDetailEventData eventData = new()
                {
                    Response = result.Data,
                };
                await EventBus?.PublishAsync(this, eventData);
            }
            return await Task.Factory.StartNew(() => result);
        }
        #endregion

        #endregion

        #region "受保护方法"
        #region "以阿里云作为服务商申请短信模板"
        /// <summary>
        /// 以阿里云作为服务商申请短信模板
        /// </summary>
        /// <param name="regionId">区域ID cn-hangzhou</param>
        /// <param name="accessKeyId">阿里云API的密钥Id</param>
        /// <param name="accessKeySecret">阿里云API的密钥Secret</param>
        /// <param name="domain">产品域名 dysmsapi.aliyuncs.com</param>
        /// <param name="paramsDto">短信模板参数DTO</param>
        /// <returns></returns>
        protected virtual OperationResult<TempResponse> AddTemplateByAliyun(string regionId, string accessKeyId, string accessKeySecret
            //, string Product <param name="Product">产品名称 Dysmsapi</param>
            , string domain
            , TempParamsDto paramsDto
            )
        {
            regionId = regionId.IsMissing() ? AliyunConstants.RegionId : regionId;
            //Product = Product.IsMissing() ? AliyunConstants.Product : Product;
            domain = domain.IsMissing() ? AliyunConstants.Domain : domain;

            Check.NotNullOrEmpty(accessKeyId, nameof(accessKeyId));
            Check.NotNullOrEmpty(accessKeySecret, nameof(accessKeySecret));

            Check.NotNull(paramsDto, nameof(paramsDto));

            //设置短息处理程序
            IClientProfile profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new(profile);
            CommonRequest request = new();
            request.Method = MethodType.POST;
            request.Domain = domain;
            request.Version = AliyunConstants.Version;
            request.Action = AliyunConstants.AddSmsTemplateAction;
            // request.Protocol = ProtocolType.HTTP;

            //*必填：短信类型。
            request.AddQueryParameters("TemplateType", ((int)paramsDto.TemplateType).ToString());
            //*必填：模板名称，长度为1~30个字符。
            request.AddQueryParameters("TemplateName", paramsDto.TemplateName);
            //*必填：模板内容，长度为1~500个字符。
            request.AddQueryParameters("TemplateContent", paramsDto.TemplateContent);
            //*必填：短信模板申请说明。请在申请说明中描述您的业务使用场景，长度为1~100个字符。
            request.AddQueryParameters("Remark", paramsDto.Remark);

            try
            {
                CommonResponse response = client.GetCommonResponse(request);
                var responseData = response.Data.FromJsonString<TempResponse>();
                if (!responseData.Succeeded)
                {
                    return OperationResult.Error(responseData);
                }
                return OperationResult.Success(responseData);
            }
            catch (ServerException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
            catch (ClientException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
        }
        #endregion
        #region "以阿里云作为服务商删除短信模板"
        /// <summary>
        /// 以阿里云作为服务商删除短信模板
        /// </summary>
        /// <param name="regionId">区域ID cn-hangzhou</param>
        /// <param name="accessKeyId">阿里云API的密钥Id</param>
        /// <param name="accessKeySecret">阿里云API的密钥Secret</param>
        /// <param name="domain">产品域名 dysmsapi.aliyuncs.com</param>
        /// <param name="templateCode">短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。</param>
        /// <returns></returns>
        protected virtual OperationResult<TempResponse> DeleteTemplateByAliyun(string regionId, string accessKeyId, string accessKeySecret
            //, string Product <param name="Product">产品名称 Dysmsapi</param>
            , string domain
            , string templateCode
            )
        {
            regionId = regionId.IsMissing() ? AliyunConstants.RegionId : regionId;
            //Product = Product.IsMissing() ? AliyunConstants.Product : Product;
            domain = domain.IsMissing() ? AliyunConstants.Domain : domain;

            Check.NotNullOrEmpty(accessKeyId, nameof(accessKeyId));
            Check.NotNullOrEmpty(accessKeySecret, nameof(accessKeySecret));

            Check.NotNullOrEmpty(templateCode, nameof(templateCode));

            //设置短息处理程序
            IClientProfile profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new(profile);
            CommonRequest request = new();
            request.Method = MethodType.POST;
            request.Domain = domain;
            request.Version = AliyunConstants.Version;
            request.Action = AliyunConstants.DeleteSmsTemplateAction;
            // request.Protocol = ProtocolType.HTTP;

            //*必填：短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。
            request.AddQueryParameters("TemplateCode", templateCode);

            try
            {
                CommonResponse response = client.GetCommonResponse(request);
                var responseData = response.Data.FromJsonString<TempResponse>();
                if (!responseData.Succeeded)
                {
                    return OperationResult.Error(responseData);
                }
                return OperationResult.Success(responseData);
            }
            catch (ServerException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
            catch (ClientException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
        }
        #endregion
        #region "以阿里云作为服务商修改短信模板"
        /// <summary>
        /// 以阿里云作为服务商修改短信模板
        /// </summary>
        /// <param name="regionId">区域ID cn-hangzhou</param>
        /// <param name="accessKeyId">阿里云API的密钥Id</param>
        /// <param name="accessKeySecret">阿里云API的密钥Secret</param>
        /// <param name="domain">产品域名 dysmsapi.aliyuncs.com</param>
        /// <param name="paramsDto">短信模板参数DTO</param>
        /// <returns></returns>
        protected virtual OperationResult<TempResponse> ModifyTemplateByAliyun(string regionId, string accessKeyId, string accessKeySecret
            //, string Product <param name="Product">产品名称 Dysmsapi</param>
            , string domain
            , TempParamsDto paramsDto
            )
        {
            regionId = regionId.IsMissing() ? AliyunConstants.RegionId : regionId;
            //Product = Product.IsMissing() ? AliyunConstants.Product : Product;
            domain = domain.IsMissing() ? AliyunConstants.Domain : domain;

            Check.NotNullOrEmpty(accessKeyId, nameof(accessKeyId));
            Check.NotNullOrEmpty(accessKeySecret, nameof(accessKeySecret));

            Check.NotNull(paramsDto, nameof(paramsDto));

            //设置短息处理程序
            IClientProfile profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new(profile);
            CommonRequest request = new();
            request.Method = MethodType.POST;
            request.Domain = domain;
            request.Version = AliyunConstants.Version;
            request.Action = AliyunConstants.ModifySmsTemplateAction;
            // request.Protocol = ProtocolType.HTTP;

            //*必填：短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。
            request.AddQueryParameters("TemplateCode", paramsDto.TemplateCode);

            //*必填：短信类型。
            request.AddQueryParameters("TemplateType", ((int)paramsDto.TemplateType).ToString());
            //*必填：模板名称，长度为1~30个字符。
            request.AddQueryParameters("TemplateName", paramsDto.TemplateName);
            //*必填：模板内容，长度为1~500个字符。
            request.AddQueryParameters("TemplateContent", paramsDto.TemplateContent);
            //*必填：短信模板申请说明。请在申请说明中描述您的业务使用场景，长度为1~100个字符。
            request.AddQueryParameters("Remark", paramsDto.Remark);

            try
            {
                CommonResponse response = client.GetCommonResponse(request);
                var responseData = response.Data.FromJsonString<TempResponse>();
                if (!responseData.Succeeded)
                {
                    return OperationResult.Error(responseData);
                }
                return OperationResult.Success(responseData);
            }
            catch (ServerException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
            catch (ClientException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempResponse>(e.Message);
            }
        }
        #endregion
        #region "以阿里云作为服务商查询短信模板"
        /// <summary>
        /// 以阿里云作为服务商查询短信模板
        /// </summary>
        /// <param name="regionId">区域ID cn-hangzhou</param>
        /// <param name="accessKeyId">阿里云API的密钥Id</param>
        /// <param name="accessKeySecret">阿里云API的密钥Secret</param>
        /// <param name="domain">产品域名 dysmsapi.aliyuncs.com</param>
        /// <param name="templateCode">短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。</param>
        /// <returns></returns>
        protected virtual OperationResult<TempDetailResponse> QueryTemplateByAliyun(string regionId, string accessKeyId, string accessKeySecret
            //, string Product <param name="Product">产品名称 Dysmsapi</param>
            , string domain
            , string templateCode
            )
        {
            regionId = regionId.IsMissing() ? AliyunConstants.RegionId : regionId;
            //Product = Product.IsMissing() ? AliyunConstants.Product : Product;
            domain = domain.IsMissing() ? AliyunConstants.Domain : domain;

            Check.NotNullOrEmpty(accessKeyId, nameof(accessKeyId));
            Check.NotNullOrEmpty(accessKeySecret, nameof(accessKeySecret));

            Check.NotNullOrEmpty(templateCode, nameof(templateCode));

            //设置短息处理程序
            IClientProfile profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new(profile);
            CommonRequest request = new();
            request.Method = MethodType.POST;
            request.Domain = domain;
            request.Version = AliyunConstants.Version;
            request.Action = AliyunConstants.QuerySmsTemplateAction;
            // request.Protocol = ProtocolType.HTTP;

            //*必填：短信模板CODE。您可以在控制台模板管理页面或API接口AddSmsTemplate的返回参数中获取短信模板CODE。
            request.AddQueryParameters("TemplateCode", templateCode);

            try
            {
                CommonResponse response = client.GetCommonResponse(request);
                var responseData = response.Data.FromJsonString<TempDetailResponse>();
                if (!responseData.Succeeded)
                {
                    return OperationResult.Error(responseData);
                }
                return OperationResult.Success(responseData);
            }
            catch (ServerException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempDetailResponse>(e.Message);
            }
            catch (ClientException e)
            {
                Logger.LogError(e, "{msg}", e.Message);
                return OperationResult.Error<TempDetailResponse>(e.Message);
            }
        }
        #endregion

        #endregion

    }
    #endregion

}
